package net.chat.server;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import net.chat.Forum;
import net.chat.User;

/**
 * The chat server holds a list of users allowed to use the chat service and a
 * list of all forums created. It is a singleton, so only one instance exists when
 * the web app is run on the server. It contains methods to manage forums and users.
 * @author Prabhat
 */
public class ChatServer {

    private List<User> users = new ArrayList<User>();
    private List<Forum> forums = new ArrayList<Forum>();

    private ChatServer() {
        // add some users
        addSomeUsers();
    }

    public static ChatServer getInstance() {
        return ChatServerHolder.INSTANCE;
    }

    private static class ChatServerHolder {

        private static final ChatServer INSTANCE = new ChatServer();
    }

    /* METHODS TO MANAGE FORUMS */
    // adds a new forum
    public void newForum(Forum forum) {
        synchronized (forums) {
            forums.add(forum);
        }
    }

    // returns all forums in the list
    public List<Forum> getForums() {
        return Collections.synchronizedList(forums);
    }
    // returns forum by fid

    public Forum getForum(int fid) {
        synchronized (forums) {
            for (Iterator<Forum> itr = forums.iterator(); itr.hasNext();) {
                Forum forum = itr.next();
                if (forum.getFid() == fid) {
                    return forum;
                }
            }
            return null;
        }
    }
    // deletes forum by fid

    public boolean deleteForum(int fid) {
        synchronized (forums) {
            for (Iterator<Forum> itr = forums.iterator(); itr.hasNext();) {
                Forum forum = itr.next();
                if (forum.getFid() == fid) {
                    itr.remove();
                    return true;
                }
            }
        }
        return false;
    }

    /* METHODS TO MANAGE USERS */
    // adds a new user
    public void newUser(User user) {
        synchronized (users) {
            users.add(user);
        }
    }

    // returns all users in the list
    public List<User> getUsers() {
        return Collections.synchronizedList(users);
    }
    // returns user by uid

    public User getUser(int uid) {
        synchronized (users) {
            for (Iterator<User> itr = users.iterator(); itr.hasNext();) {
                User user = itr.next();
                if (user.getUid() == uid) {
                    return user;
                }
            }
        }
        return null;
    }

    // authenticates a user by uid and pwd
    public User login(String uid, String pwd) {
        synchronized (users) {
            for (Iterator<User> itr = users.iterator(); itr.hasNext();) {
                User user = itr.next();
                Integer id = new Integer(uid);
                if (user.login(id.intValue(), pwd)) {
                    return user;
                }
            }
        }
        return null;
    }

    // deletes user by uid
    // user is also logout out first and remove from any forum
    public boolean deleteUser(int uid) {
        synchronized (users) {
            for (Iterator<User> itr = users.iterator(); itr.hasNext();) {
                User user = itr.next();
                if (user.getUid() == uid) {
                    List<Forum> forums = getForums();
                    for (Iterator<Forum> itrF = forums.iterator(); itrF.hasNext();) {
                        Forum forum = itrF.next();
                        if (forum.getUsers().contains(user)) {
                            forum.getUsers().remove(user);
                        }
                    }
                    itr.remove();
                    return true;
                }
            }
        }
        return false;
    }

    // logs user out by removing user from any forum.
    public void logout(int uid) {
        User user = getUser(uid);
        if (user != null) {
            synchronized (forums) {
                for (Iterator<Forum> itrF = forums.iterator(); itrF.hasNext();) {
                    Forum forum = itrF.next();
                    if (forum.getUsers().contains(user)) {
                        forum.getUsers().remove(user);
                    }
                }
            }
        }
    }

    private void addSomeUsers() {
        User u1 = new User("Prabhat", "Totoo", "pt114");
        User u2 = new User("Amir", "Ghaffari", "ag275");
        User u3 = new User("Zaid", "Alzaid", "za92");
        User u4 = new User("Shamsudeen", "Usman", "ssu3");
        users.add(u1);
        users.add(u2);
        users.add(u3);
        users.add(u4);
    }
}
